package com.joe.demo.nio.io;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description 非阻塞模式
 * @Author gaojw
 * @Date 2024-08-28
 */
@Slf4j
public class NoBlockServer {

    public static void main(String[] args) throws IOException {
        // 使用 nio 来理解非阻塞模式, 单线程
        // 0. ByteBuffer
        final ByteBuffer buffer = ByteBuffer.allocate(16);
        // 1. 创建服务器
        ServerSocketChannel server = ServerSocketChannel.open();
        // 非阻塞模式
        server.configureBlocking(false);
        // 2. 绑定监听的端口
        server.bind(new InetSocketAddress(8080));
        // 3.连接集合
        List<SocketChannel> channelList = new ArrayList<>();

        while (true){
            // 4. accept 建立于客户端之间的连接, SocketChannel 用来与客户端之间通信
            // 非阻塞，线程还会继续运行，如果没有建立连接，socketChannel 是 null
            final SocketChannel socketChannel = server.accept();
            if (socketChannel != null){
                log.info("connected, {}", socketChannel);
                // 配置非阻塞
                socketChannel.configureBlocking(false);
                channelList.add(socketChannel);
            }

            for (SocketChannel channel : channelList) {
                // 5. 接收客户端发送的数据
                // 非阻塞，线程还会继续运行，read 返回 0
                final int read = channel.read(buffer);
                if (read > 0) {
                    buffer.flip();
                    log.info("接收到客户端的数据: {}", StandardCharsets.UTF_8.decode(buffer));
                    buffer.clear();
                    log.info("after read, {}", channel);
                }
            }
        }

    }
}
